/*
 * Copyright 2016-2036 the original author or authors.
 * 
 * COMMERCIAL USE OF THIS SOFTWARE WITHOUT WARRANTY IS NOT ALLOWED.
 * Use is subject to license terms! You can distribute a copy of this software
 * to others for free. This software is a non-profit and open-source project.
 * Any contribution to this project will make it better.
 * All rights reserved! Owned by Stephen Liu.
 * 
 */
package com.github.hingo.function;


import com.github.hingo.api.Nullable;

/**
 * @author ste7en.liu@gmail.com
 * @since 2016/10/18
 */
public interface Action<T> {

    void execute(T t) throws Exception;

    static Action<Object> noop() {
        return x -> {};
    }

    static <T> Action<? super T> noopIfNull(@Nullable Action<T> action) {
        if (action == null) {
            return noop();
        }
        return action;
    }

    @SafeVarargs
    static <T> Action<T> join(Action<? super T>... actions) {
        return x -> {
            for (Action<? super T> action : actions) {
                action.execute(x);
            }
        };
    }

    default <S extends T> Action<S> append(Action<? super S> action) {
        Action<T> self = this;
        return x -> {
            self.execute(x);
            action.execute(x);
        };
    }

    default <S extends T> Action<S> prepend(Action<? super S> action) {
        return action.append(this);
    }

    default <S extends T> S with(S s) throws Exception {
        execute(s);
        return s;
    }

    static <T> T with(T t, Action<? super T> action) throws Exception {
        return action.with(t);
    }
}
